package com.oba.base.dao;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.oba.base.interfaces.IHsqlBuilder;

public class HsqlBuilder implements IHsqlBuilder {

	/**
	 * 条件限制对象
	 */
	private class Restriction {
		String condtiton;

		Object value;

		Restriction(String condtiton, Object value) {
			this.condtiton = condtiton;
			this.value = value;
		}
	}

	private BaseDao dao;
	private String sqlpre;

	private List restrictions;

	private String sqlend;

	private String hsql;

	private Object[] values;
	private boolean isNeedBuild;

	private HsqlBuilder(String sqlpre, BaseDao baseDao) {
		isNeedBuild = true;
		this.sqlpre = sqlpre;
		restrictions = new ArrayList();
		dao = baseDao;
	}

	private HsqlBuilder(String sql, Object[] params, BaseDao dao2) {
		isNeedBuild = false;
		this.hsql = sql;
		this.values = params;
		dao = dao2;
	}

	/**
	 * 构建一新的HSQL
	 * 
	 * @param sqlpre
	 * @return
	 */
	static IHsqlBuilder create(String sqlpre, BaseDao baseDao) {
		return new HsqlBuilder(sqlpre, baseDao);
	}

	static IHsqlBuilder create(String sql, Object[] params, BaseDao dao) {
		return new HsqlBuilder(sql, params, dao);
	}

	private boolean paramIsNotNull(Object param) {
		if (param == null)
			return false;
		else {
			String pv = param.toString().trim();
			return !(pv.equals("") || pv.equals("0"));
		}
	}

	public IHsqlBuilder add(String condtion, Object param) {
		if (paramIsNotNull(param))
			restrictions.add(new Restriction(condtion, param));
		return this;
	}

	public IHsqlBuilder add(String condtion, Object param, String endwildcard) {
		if (paramIsNotNull(param))
			restrictions.add(new Restriction(condtion, param + endwildcard));
		return this;
	}

	public IHsqlBuilder add(String condtion, Object param, String prewildcard, String endwildcard) {
		if (paramIsNotNull(param))
			restrictions.add(new Restriction(condtion, prewildcard + param + endwildcard));
		return this;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.scom.base.dao.IHsqlBuilder#add(java.lang.String)
	 */
	public IHsqlBuilder add(String condtion) {
		restrictions.add(condtion);
		return this;
	}

	public IHsqlBuilder addend(String sqlend) {
		this.sqlend = sqlend;
		return this;
	}

	public void build() {
		if (isNeedBuild) {
			List<String> condtions = new ArrayList<String>();
			List<Object> params = new ArrayList();
			for (int i = 0; i < restrictions.size(); i++) {
				Object conobj = restrictions.get(i);
				if (conobj instanceof Restriction) {
					Restriction res = (Restriction) conobj;
					if (res.value instanceof HsqlBuilder) {
						IHsqlBuilder subsqlbuiler = (IHsqlBuilder) res.value;
						subsqlbuiler.build();
						StringBuffer sb = new StringBuffer(res.condtiton);
						sb.append("(");
						sb.append(subsqlbuiler.getHsql());
						sb.append(")");
						condtions.add(sb.toString());
						params.addAll(Arrays.asList(subsqlbuiler.getValues()));
					} else {
						condtions.add(res.condtiton);
						params.add(res.value);
					}
				} else
					condtions.add((String) conobj);
			}
			StringBuffer hsqlSb = new StringBuffer(sqlpre);
			hsqlSb.append(" ");
			if (condtions.size() > 0) {
				hsqlSb.append("where ");
				hsqlSb.append(condtions.get(0));
			}
			for (int i = 1; i < condtions.size(); i++) {
				hsqlSb.append(" and ");
				hsqlSb.append(condtions.get(i));
			}
			if (sqlend != null) {
				hsqlSb.append(" ");
				hsqlSb.append(sqlend);
			}
			hsql = hsqlSb.toString();
			values = params.toArray();
		}
	}

	public String getHsql() {
		return hsql;
	}

	public Object[] getValues() {
		return values;
	}

	public BaseDao getDao() {
		return dao;
	}

}
